SETUP PACKAGES AND READ IN IMAGES¶
InĀ [2]:
#import needed libraries
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
import tensorflow as tf
import tensorflow_hub as hub
import os
import cv2
import imghdr
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten
from tensorflow.keras import layers
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tf_keras\src\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.
C:\Users\eebla\AppData\Local\Temp\ipykernel_36408\1819497594.py:9: DeprecationWarning: 'imghdr' is deprecated and slated for removal in Python 3.13 import imghdr
InĀ [3]:
#getting rid of images that are not the correct extension or are corrupt.
# also manually got rid of small images <10KB
data_dir = (r'C:\Users\eebla\OneDrive\Documents\side_project')
image_exts = ['jpeg','jpg', 'bmp', 'png']
for image_class in os.listdir(data_dir):
for image in os.listdir(os.path.join(data_dir, image_class)): #it is looping through each of the folders and then all the images in each
image_path = os.path.join(data_dir, image_class, image)
try:
img = cv2.imread(image_path)
tip = imghdr.what(image_path)
if tip not in image_exts:
print('Image not in ext list {}'.format(image_path))
os.remove(image_path)
except Exception as e:
print('Issue with image {}'.format(image_path))
LOAD IN IMAGES WITH TENSORFLOW¶
InĀ [5]:
#I dont have an NVIDIA graphis card:(
# fun fact if a filename is in chinese it breaks it
#defualt size is 256,256 and 32 per batch, shuffle is true going to need to get them to 224x224 for transfer learning model
#tf.keras.utils.image_dataset_from_directory??
#set wanted image size
IMAGE_SIZE=[224,224]
#set up the directory, tf likes to have subfolders with labels
data_dir = (r'C:\Users\eebla\OneDrive\Documents\side_project')
data= tf.keras.utils.image_dataset_from_directory(data_dir,image_size=(IMAGE_SIZE))
Found 552 files belonging to 2 classes.
InĀ [6]:
#iterate through images and look at some of them
#dachshunds are labeled as 1 and chihuahuas are labled as 0
# can run this a bunch and see different batches of 32
data_iterator = data.as_numpy_iterator() #images represented by numpy arrays, grabs batches of 32
batch = data_iterator.next()
batch[0] #this is the arrays reprensting the image
batch[1] #this array represents the labels aka dachshund or seal
fig, ax = plt.subplots(ncols=4, figsize=(26,26))
for idx, img in enumerate(batch[0][:4]):
ax[idx].imshow(img.astype(int))
ax[idx].title.set_text(batch[1][idx])
InĀ [8]:
# SCALE- need to scale the arrays from 0 to 1 instead of 0 to 255 (the color scale goes to 255), its in RGB with tensorflow, its BGR with open_cv.
#tensorflow data api -> can see what other functions you can do in the pipeline
#Need to apply this to the pipeline instead of doing it after batch comes in
#x is the images and y is the labels
data=data.map(lambda x,y:(x/255,y)) #the map function is from tf
batch=data.as_numpy_iterator().next()
#checking, looks good this will work.
print(f'Min: {batch[0].min()}')
print(f'Max: {batch[0].max()}')
#they are all black
fig, ax = plt.subplots(ncols=4, figsize=(128,128))
for idx, img in enumerate(batch[0][:4]):
ax[idx].imshow(img) #take out as type is int because they would all be 0 since we scaled it
ax[idx].title.set_text(batch[1][idx])
Min: 0.0 Max: 1.0
SPLIT INTO TRAIN, VALIDATE AND TEST¶
InĀ [10]:
print(len(data)) #there are 18 batches of 32
train_size = int(len(data)*.7) #12
val_size = int(len(data)*.2) #3
test_size = int(len(data)*.1) #1
print(train_size)
print(val_size)
print(test_size)
#the take is telling how many batches to do, data is shuffled so there are a mix of 0s and 1s in each batch
train = data.take(train_size)
val = data.skip(train_size).take(val_size)
test = data.skip(train_size+val_size).take(test_size)
18 12 3 1
CNN with augmentation and transfer learning¶
InĀ [12]:
import tf_keras as tfk
input_shape = (None,224, 224, 3)
hub_url = "https://www.kaggle.com/models/google/mobilenet-v2/TensorFlow2/035-224-feature-vector/2"
model = tfk.Sequential([
tfk.layers.RandomFlip(mode='horizontal'), #randomly flips horizontal
tfk.layers.RandomRotation(0.1), #randomly rotates
tfk.layers.RandomZoom(0.1),
hub.KerasLayer(hub_url, trainable=False), # Can be True, see below.
tfk.layers.Flatten(),
tfk.layers.Dense(1, activation='sigmoid') # output layer
])
# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.build(input_shape)
model.summary()
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tf_keras\src\backend.py:873: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead. WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tensorflow_hub\resolver.py:120: The name tf.gfile.MakeDirs is deprecated. Please use tf.io.gfile.makedirs instead.
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tensorflow_hub\resolver.py:120: The name tf.gfile.MakeDirs is deprecated. Please use tf.io.gfile.makedirs instead.
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tensorflow_hub\module_v2.py:126: The name tf.saved_model.load_v2 is deprecated. Please use tf.compat.v2.saved_model.load instead.
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tensorflow_hub\module_v2.py:126: The name tf.saved_model.load_v2 is deprecated. Please use tf.compat.v2.saved_model.load instead.
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tf_keras\src\optimizers\__init__.py:317: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tf_keras\src\optimizers\__init__.py:317: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
random_flip (RandomFlip) (None, 224, 224, 3) 0
random_rotation (RandomRot (None, 224, 224, 3) 0
ation)
random_zoom (RandomZoom) (None, 224, 224, 3) 0
keras_layer (KerasLayer) (None, 1280) 410208
flatten (Flatten) (None, 1280) 0
dense (Dense) (None, 1) 1281
=================================================================
Total params: 411489 (1.57 MB)
Trainable params: 1281 (5.00 KB)
Non-trainable params: 410208 (1.56 MB)
_________________________________________________________________
InĀ [13]:
#fitting model on training- validation went down around 10 then went back up
hist = model.fit(train, epochs=10, validation_data=val)
Epoch 1/10 WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tf_keras\src\utils\tf_utils.py:492: The name tf.ragged.RaggedTensorValue is deprecated. Please use tf.compat.v1.ragged.RaggedTensorValue instead.
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tf_keras\src\utils\tf_utils.py:492: The name tf.ragged.RaggedTensorValue is deprecated. Please use tf.compat.v1.ragged.RaggedTensorValue instead.
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tf_keras\src\engine\base_layer_utils.py:384: The name tf.executing_eagerly_outside_functions is deprecated. Please use tf.compat.v1.executing_eagerly_outside_functions instead.
WARNING:tensorflow:From C:\Users\eebla\anaconda3\Lib\site-packages\tf_keras\src\engine\base_layer_utils.py:384: The name tf.executing_eagerly_outside_functions is deprecated. Please use tf.compat.v1.executing_eagerly_outside_functions instead.
12/12 [==============================] - 13s 475ms/step - loss: 0.5000 - accuracy: 0.7188 - val_loss: 0.3683 - val_accuracy: 0.7812 Epoch 2/10 12/12 [==============================] - 5s 368ms/step - loss: 0.2490 - accuracy: 0.8880 - val_loss: 0.1448 - val_accuracy: 0.9583 Epoch 3/10 12/12 [==============================] - 5s 406ms/step - loss: 0.1514 - accuracy: 0.9740 - val_loss: 0.1287 - val_accuracy: 0.9792 Epoch 4/10 12/12 [==============================] - 5s 401ms/step - loss: 0.1070 - accuracy: 0.9818 - val_loss: 0.0827 - val_accuracy: 0.9896 Epoch 5/10 12/12 [==============================] - 4s 348ms/step - loss: 0.0904 - accuracy: 0.9870 - val_loss: 0.0702 - val_accuracy: 1.0000 Epoch 6/10 12/12 [==============================] - 6s 472ms/step - loss: 0.0792 - accuracy: 0.9870 - val_loss: 0.0524 - val_accuracy: 1.0000 Epoch 7/10 12/12 [==============================] - 9s 722ms/step - loss: 0.0544 - accuracy: 0.9948 - val_loss: 0.0342 - val_accuracy: 1.0000 Epoch 8/10 12/12 [==============================] - 8s 642ms/step - loss: 0.0445 - accuracy: 0.9948 - val_loss: 0.0596 - val_accuracy: 0.9896 Epoch 9/10 12/12 [==============================] - 5s 421ms/step - loss: 0.0496 - accuracy: 0.9896 - val_loss: 0.0403 - val_accuracy: 0.9896 Epoch 10/10 12/12 [==============================] - 6s 503ms/step - loss: 0.0446 - accuracy: 0.9948 - val_loss: 0.0280 - val_accuracy: 1.0000
PLOT THE PERFORMANCE¶
InĀ [15]:
#hist.history can see the accuracy, loss is stored for training and validation
#looks great, both the training and validation loss is decreasing over time
#plot loss
fig = plt.figure()
plt.plot(hist.history['loss'], color='teal', label='loss') #traiing loss
plt.plot(hist.history['val_loss'], color='orange', label='val_loss') #validation loss
fig.suptitle('Loss', fontsize=20)
plt.legend(loc="upper left")
plt.show()
InĀ [16]:
#plot accuracy
fig = plt.figure()
plt.plot(hist.history['accuracy'], color='teal', label='accuracy') #training accuracy
plt.plot(hist.history['val_accuracy'], color='orange', label='val_accuracy') #validation accuracy
fig.suptitle('Accuracy', fontsize=20)
plt.legend(loc="upper left")
plt.show()
EVALUATION ON TEST SET¶
InĀ [18]:
loss, acc = model.evaluate(test)
print(f"Test Loss: {loss}, Test Accuracy: {acc}")
1/1 [==============================] - 2s 2s/step - loss: 0.0169 - accuracy: 1.0000 Test Loss: 0.01686013862490654, Test Accuracy: 1.0
MORE testing¶
InĀ [20]:
#test on my dachshunds Cannoli and Biscotti and my old boss's chihuahua peachy
#since we are using open cv its showing them in bgr that is why it looks a little off colorwise, fixed it
#Cannoli
img_c = cv2.imread(r'C:\Users\eebla\OneDrive\Documents\cannoli.jpg')
plt.imshow(cv2.cvtColor(img_c,cv2.COLOR_BGR2RGB))
plt.show()
#Biscotti
img_b= cv2.imread(r'C:\Users\eebla\OneDrive\Documents\biscotti.jpg')
plt.imshow(cv2.cvtColor(img_b,cv2.COLOR_BGR2RGB))
plt.show()
#Biscotti 2
img_b2= cv2.imread(r'C:\Users\eebla\OneDrive\Documents\biscotti2.jpg')
plt.imshow(cv2.cvtColor(img_b2,cv2.COLOR_BGR2RGB))
plt.show()
#both my dogs
img_both= cv2.imread(r'C:\Users\eebla\OneDrive\Documents\both.jpg')
plt.imshow(cv2.cvtColor(img_both,cv2.COLOR_BGR2RGB))
plt.show()
#seal teset image
img_p1= cv2.imread(r'C:\Users\eebla\OneDrive\Documents\seal_test.jpg')
plt.imshow(cv2.cvtColor(img_p1,cv2.COLOR_BGR2RGB))
plt.show()
#seal test image
img_p2= cv2.imread(r'C:\Users\eebla\OneDrive\Documents\seal_test_2.jpg')
plt.imshow(cv2.cvtColor(img_p2,cv2.COLOR_BGR2RGB))
plt.show()
InĀ [21]:
#we need to resize these images before passing through neural network
resize_c = tf.image.resize(img_c, IMAGE_SIZE)
resize_b = tf.image.resize(img_b, IMAGE_SIZE)
resize_b2 = tf.image.resize(img_b2,IMAGE_SIZE)
resize_both = tf.image.resize(img_both, IMAGE_SIZE)
resize_p1 = tf.image.resize(img_p1, IMAGE_SIZE)
resize_p2= tf.image.resize(img_p2, IMAGE_SIZE)
# checking, it works
#plt.imshow(resize_c.numpy().astype(int))
#plt.show()
InĀ [35]:
#scale and predict
yhatc = model.predict(np.expand_dims(resize_c/255, 0))
yhatb = model.predict(np.expand_dims(resize_b/255, 0))
yhatb2 = model.predict(np.expand_dims(resize_b2/255, 0))
yhatboth = model.predict(np.expand_dims(resize_both/255, 0))
yhatp1 = model.predict(np.expand_dims(resize_p1/255, 0))
yhatp2 = model.predict(np.expand_dims(resize_p2/255, 0))
#function to print out what the predictions are
def what_dog(pred):
if pred > 0.5:
print(f'Predicted class is a Seal: {pred}')
else:
print(f'Predicted class is a Dachshund: {pred}')
#got them all correct
what_dog(yhatc)
what_dog(yhatb)
what_dog(yhatb2)
what_dog(yhatboth)
what_dog(yhatp1)
what_dog(yhatp2)
1/1 [==============================] - 1s 1s/step 1/1 [==============================] - 1s 510ms/step 1/1 [==============================] - 1s 834ms/step 1/1 [==============================] - 1s 746ms/step 1/1 [==============================] - 1s 597ms/step 1/1 [==============================] - 1s 923ms/step Predicted class is a Dachshund: [[0.00379731]] Predicted class is a Dachshund: [[0.0075904]] Predicted class is a Dachshund: [[0.09564621]] Predicted class is a Dachshund: [[0.16695812]] Predicted class is a Seal: [[0.9739798]] Predicted class is a Seal: [[0.93229675]]